package com.wang.hrm.service.impl;


import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.wang.hrm.constants.RedisConstants;
import com.wang.hrm.domain.CourseType;
import com.wang.hrm.feign.client.RedisFeignClient;
import com.wang.hrm.mapper.CourseTypeMapper;
import com.wang.hrm.service.ICourseTypeService;
import com.wang.hrm.util.AjaxResult;
import com.wang.hrm.vo.CrumbsVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author whale.chen
 * @since 2020-04-18
 */
@Service
@Transactional
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {

    @Autowired
    private RedisFeignClient redisFeignClient;

    //查询课程分类，加入缓存逻辑 ：注意，Redis存储的是没有处理过的课程分类
    private List<CourseType> selectCourseTypeFromCache(){
        //1.从Redis中查询课程分类
        AjaxResult ajaxResultFromRedis = redisFeignClient.get(RedisConstants.KEY_COURSE_TYPE);

        if(ajaxResultFromRedis.isSuccess() && ajaxResultFromRedis.getResultObj() != null){
            //正常拿到了数据
            //2.如果Redis有课程分类
            //2.1.把课程分类取出来
            String courseTypeJson = ajaxResultFromRedis.getResultObj().toString();

            //2.2.把json数据转成list
            return JSON.parseArray(courseTypeJson, CourseType.class);
        }

        //3.如果Redis没有课程分类
        //3.1.就去MySql查询课程分类
        //3.2.把课程分类数据存储到Redis
        List<CourseType> courseTypes = courseTypeToRedisFromMySql();

        //4.返回课程分类
        return courseTypes;
    }

    private List<CourseType> courseTypeToRedisFromMySql() {
        //3.1.就去MySql查询课程分类
        List<CourseType> courseTypes = baseMapper.selectList(null);

        //3.2.把课程分类数据存储到Redis
        redisFeignClient.set(RedisConstants.KEY_COURSE_TYPE, JSON.toJSONString(courseTypes));
        return courseTypes;
    }

    //思考：返回的结果数据结构？CourseType的 List ， 每个CourseType有children装子分类列表
    //思考：返回的结果的List的条数是多少？一级分类的条数 5 条
    @Override
    public List<CourseType> treeData() {
        //结果List ： 5条数据
        List<CourseType> parentCourseTypeList = new ArrayList<>( );
        //1.把所有的分类数据查询出来
        //查询出 26条数
        List<CourseType> allCourseType = selectCourseTypeFromCache();//baseMapper.selectList(null);
        allCourseType.forEach(currentCourseType ->{
            //2.把一级分类找出来，装到List中
            if(currentCourseType.getPid() == 0){
                //currentCourseType 到这里，就是一级
                parentCourseTypeList.add(currentCourseType);
            }else{
                //currentCourseType 到这里，可能是二级，也有可能是三级。
                //3.除开一级分类的其他所有的分类，都去找自己的父分类，装到父分类的children
                //3.1.找自己的父分类 ：父分类的 id = currentCourseType.pid
                for(CourseType parentCouresType : allCourseType){
                    //父分类的 id = currentCourseType.pid
                    if(currentCourseType.getPid().equals(parentCouresType.getId())){
                        //3.2.加入自己的父分类的children
                        parentCouresType.getChildren().add(currentCourseType);
                        break;
                    }
                }
            }
        });
        return parentCourseTypeList;
    }

    @Override
    public List<CrumbsVo> crumbs(Long courseTypeId) {
        //1.根据当前分类ID查询出当前分类： 1040
        CourseType courseType = baseMapper.selectById(courseTypeId);

        //2.获取当前分类的path，然后切割成数组(id数组) ：1037.1039.1040  -> [1037 ,1039 ,1040]
        String[] courseTypeIdStr = courseType.getPath().split("\\.");

        List<Long> ids = new ArrayList<>();
        for(String idStr : courseTypeIdStr){
            ids.add(Long.valueOf(idStr));
        }

        //3.通过课程分类的id数组,批量查询课程分类列表 ：[courseType,CourseType,CourseType]
        List<CourseType> courseTypes = baseMapper.selectBatchIds(ids);

        //4.遍历程分类列表，每个课程分类就是一个CrumbsVo : [CrumbsVo , CrumbsVo, CrumbsVo]

        //结果
        List<CrumbsVo> result = new ArrayList<>() ;
        courseTypes.forEach( currentCourseType -> {
            //把当前课程分类 currentCourseType ,封装到  CrumbsVo.OwnerProductType
            CrumbsVo  vo = new CrumbsVo();
            vo.setOwnerProductType(currentCourseType);

            //5.为每一个课程类型找他的兄弟姐妹列表，设置到CrumbsVo.otherProductTypes列表中
            Long pid = currentCourseType.getPid();
            List<CourseType> otherProductTypes = baseMapper.selectListByPid(pid);
            vo.setOtherProductTypes(otherProductTypes);
            result.add(vo);
        });

        //6.最后返回结果List
        return result;
    }


    @Override
    public boolean insert(CourseType entity) {

        boolean result = super.insert(entity);
        if(result){
            //保存成功后，重置缓存(清空也可以)
            //1.从数据库查询课程分类
            //2.把课程分类保存到Redis
            courseTypeToRedisFromMySql();
        }
        return result ;
    }

    @Override
    public boolean deleteById(Serializable id) {
        boolean result = super.deleteById(id);
        if(result){
            //保存成功后，重置缓存(清空也可以)
            //1.从数据库查询课程分类
            //2.把课程分类保存到Redis
            courseTypeToRedisFromMySql();
        }
        return result ;
    }

    @Override
    public boolean updateById(CourseType entity) {
        boolean result = super.updateById(entity);
        if(result){
            //保存成功后，重置缓存(清空也可以)
            //1.从数据库查询课程分类
            //2.把课程分类保存到Redis
            courseTypeToRedisFromMySql();
        }
        return result ;
    }
}
